package org.tinygroup.template.interpret.terminal;

import java.io.OutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.antlr.v4.runtime.tree.TerminalNode;
import org.tinygroup.template.TemplateContext;
import org.tinygroup.template.TemplateRender;
import org.tinygroup.template.impl.TemplateRenderDefault;
import org.tinygroup.template.interpret.TemplateFromContext;
import org.tinygroup.template.interpret.TerminalNodeProcessor;

/**
 * 字符串的抽象处理节点
 * @author yancheng11334
 *
 */
public abstract class AbstractStringNodeProcessor implements TerminalNodeProcessor<TerminalNode> {

	private static final String rule = "[$][{][^}]*[}]";
	private static final Pattern pattern = Pattern.compile(rule);
	
	public boolean processChildren() {
        return false;
    }
	
	public Object process(TerminalNode terminalNode, TemplateContext context,
			OutputStream outputStream, TemplateFromContext templateFromContext)
			throws Exception {
		String text = templateFromContext.getObject(terminalNode);
        if (text == null) {
            text = getText(terminalNode);
            if(pattern.matcher(text).find()) {
                // 进行$渲染
                Matcher matcher = pattern.matcher(text);
                StringBuilder sb = new StringBuilder();
                int pos = 0;
                TemplateRender render = new TemplateRenderDefault();
                render.setTemplateEngine(templateFromContext.getTemplateEngine());
                while (matcher.find()) {
                   String group = matcher.group();
                   sb.append(text.substring(pos, matcher.start()));
                   sb.append(render.renderTemplateContent(group, context));
                   pos = matcher.end();
                }
                sb.append(text.substring(pos));
                //返回动态结果，不保留缓存
                return sb.toString();
            }else{
            	// 直接保存缓存
                templateFromContext.putObject(terminalNode, text);
            }
        }
        return text;
	}

	/**
	 * 提取字符串内容
	 * @param terminalNode
	 * @return
	 */
	protected abstract String getText(TerminalNode terminalNode);

}
